/*
 * TimerControl.c
 *
 *  Created on: 27.09.2011
 *      Author: windows97
 */

#include <avr/io.h>
#include <avr/interrupt.h>
#include <string.h>
#include "EleAl.h"
#include "TimeDate.h"
#include "TimerControl.h"

#define HEARTBEAT_NO_OF_NOTIFICATIONS 3
#define TIMER_INVALID_NOTIFICATION_U8   ((uint8_t) (0xff))

static T_HeartbeatNotify gTicNotifications_at[HEARTBEAT_NO_OF_NOTIFICATIONS];

void TicInit( void )
{
  uint8_t lCount = 0;
  for( lCount = 0; lCount < HEARTBEAT_NO_OF_NOTIFICATIONS; lCount++ )
  {
    gTicNotifications_at[lCount] = NULL;
  }

  TCCR1B = (1 << CS11); // divide by 8
  // clear on compare

  OCR1A = HEARTBEAT_1_U16;
  TIMSK1 |= (1 << OCIE1A);
  // Output Compare Register
  TCNT1 = 0; /* Timer starts with 0 */
}

uint8_t TicRegisterNotification( T_HeartbeatNotify iNotifyFunction )
{
  uint8_t lCount = 0;
  uint8_t lFreeSlot = TIMER_INVALID_NOTIFICATION_U8;
  for( lCount = 0; lCount < HEARTBEAT_NO_OF_NOTIFICATIONS; lCount++ )
  {
    if( gTicNotifications_at[lCount] == NULL )
    {
        lFreeSlot = lCount;
    }
  }
  if( lFreeSlot != TIMER_INVALID_NOTIFICATION_U8 )
  {
    if( iNotifyFunction != NULL )
    {
      gTicNotifications_at[lFreeSlot]      = iNotifyFunction;
    }
  }
  return (lFreeSlot);
}

void TicClearNotification( uint8_t iSlot_u8 )
{
  uint8_t lCount_u8 = 0;
  for( lCount_u8 = 0; lCount_u8 < HEARTBEAT_NO_OF_NOTIFICATIONS; lCount_u8++ )
  {
    if( iSlot_u8 == lCount_u8 )
    {
      gTicNotifications_at[lCount_u8] = NULL;
    }
  }
}

void TicSyncCounter( void )
{
  OCR1A = TCNT1 + HEARTBEAT_1_U16;
}

ISR(TIMER1_COMPA_vect)
{
  OCR1A += HEARTBEAT_1_U16;
  /* call hheartbeat indications */
  for( uint8_t lCount = 0; lCount < HEARTBEAT_NO_OF_NOTIFICATIONS; lCount++ )
  {
    if( gTicNotifications_at[lCount] != NULL )
    {
      gTicNotifications_at[lCount]();
    }
  }
}
